/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief Valgrind wrapper for Gimbo components.
 * \author Antti Maula <antti.maula@tkk.fi>
 *
 * Configuration file is constructed by creating a file with same name
 * as this binary plus ".conf" appended. The file must be located on
 * the same path as given in parameter 'argv[0]'. (The name is
 * constructed by concatenating argv[0] + ".conf")
 *
 * Files contents must be formatted like:
 * <working directory to change to>\n
 * <application>\n
 * <valgrind parameters>\n
 * [whatever you like :) ...]
 *
 * As a result, the application will be executed using the read
 * values. All parameters passed to this binary, are passed as is to
 * the initiated application.
 */
#include <stdlib.h>
#include <stdio.h>
#include <string>

int main(int argc, char *argv[])
{
  int result = 1;
  int r;
  std::string workdir;
  std::string valgrindparam;
  std::string app;
  std::string param;
  std::string final_command;

  const std::string confname = std::string(argv[0]) + std::string(".conf");
  FILE *vgwrapc = fopen(confname.c_str(), "rb");
  if (vgwrapc) {
    char tmp[1024];

    // Read workdir
    if ( fgets(tmp, sizeof(tmp), vgwrapc) == NULL ) {
      perror("Failed to read WorkingDirectory");
      exit(1);

    } else {
      workdir = tmp;
      workdir.resize(workdir.size()-1);
      printf("Workdir set to: '%s'\n", workdir.c_str());
    }
    
    // Read app
    if ( fgets(tmp, sizeof(tmp), vgwrapc) == NULL ) {
      perror("Failed to read Application");
      exit(1);
      
    } else {
      app = tmp;
      app.resize(app.size()-1);
      printf("Application set to: '%s'\n", app.c_str());
    }
    
    // Read Valgrind param
    if ( fgets(tmp, sizeof(tmp), vgwrapc) == NULL ) {
      perror("Failed to read ValgrindParam");
      exit(1);
      
    } else {
      valgrindparam = tmp;
      valgrindparam.resize(valgrindparam.size()-1);
      printf("Valgrindparam set to: '%s'\n", valgrindparam.c_str());
    }

  } else {
    printf("'%s' not found. Please create it.\n", confname.c_str());
    exit(1);
  }

  // Store param (Always add space)
  for (int i=1; i < argc; ++i) {
    param += std::string(" ") + std::string(argv[i]);
  }

  // Construct final command.
  // final_command = "valgrind " + valgrindparam + " " + app + param;
  //final_command = "konsole --nofork valgrind " + valgrindparam + " " + app + param;
  final_command = "konsole --nofork --workdir " + std::string(workdir) + " -e valgrind " + valgrindparam + " " + app + param;

  //// Execute.
  // Change wd.
  r = chdir(workdir.c_str());
  if (r == 0) {
    char wd[1024];
    printf("Valgrind Wrapper :: Executing final command: '%s' in current directory: '%s'\n",
           final_command.c_str(), getcwd(wd, sizeof(wd)));
    result = system(final_command.c_str());
  }


  return result;
}

/**
 * 
 * $Id: ValgrindWrapper.cpp,v 1.3 2009-05-05 11:50:17 amaula Exp $
 *
 ******************************************************************************
 *
 * $Log: not supported by cvs2svn $
 * Revision 1.2  2009-05-05 09:39:24  amaula
 * Minor cleanups done and document-like texts added.
 *
 * Revision 1.1  2009-05-05 09:21:46  amaula
 * Wrapper added for Valgrind.
 *
 *
 */
